package com.bzchao.wechat.service;

import com.bzchao.wechat.wxopen.dto.response.UserInfo;
import com.bzchao.wechat.wxopen.dto.response.WechatToken;
import com.bzchao.wechat.wxopen.constant.WeChatConstant;
import com.bzchao.wechat.wxopen.msg.BaseMessage;
import com.bzchao.wechat.wxopen.msg.TextMessage;
import com.bzchao.wechat.common.utils.JsonUtils;
import com.bzchao.wechat.utils.JaxpUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.client.RestTemplate;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 核心服务类
 */
@Slf4j
@Service
public class WeChatServiceImpl implements WeChatService {
    //缓存用户信息(实际业务最好存数据库）
    private static Map<String, UserInfo> userMap = new ConcurrentHashMap<>();

    @Value("${wechat.appId}")
    private String appId;
    @Value("${wechat.appSecret}")
    private String appSecret;

    @Override
    public TextMessage generateTextMessage(String toUser, String fromUser, String content) {
        TextMessage textMessage = new TextMessage();
        textMessage.setToUserName(toUser);
        textMessage.setFromUserName(fromUser);
        textMessage.setContent(content);
        textMessage.setCreateTime(new Date().getTime());
        textMessage.setMsgType(WeChatConstant.RESP_MESSAGE_TYPE_TEXT);
        return textMessage;
    }

    @Override
    public WechatToken getToken(String appId, String appSecret) {
        RestTemplate restTemplate = new RestTemplate();
        String url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={appId}&secret={appSecret}";
        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("appId", appId);
        paramMap.put("appSecret", appSecret);
        ResponseEntity<WechatToken> entity = restTemplate.getForEntity(url, WechatToken.class, paramMap);
        return entity.getBody();
    }

    @Override
    public UserInfo getUserInfoByAuthCode(String authCode) {
        if (userMap.containsKey(authCode)) {
            return userMap.get(authCode);
        }
        RestTemplate restTemplate = new RestTemplate();

        String url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid={appId}&secret={appSecret}&code={code}&grant_type=authorization_code";
        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("appId", appId);
        paramMap.put("appSecret", appSecret);
        paramMap.put("code", authCode);
        ResponseEntity<String> entity = restTemplate.getForEntity(url, String.class, paramMap);
        log.info("查询用户信息：{}", entity.getBody());
        UserInfo userInfo = JsonUtils.toObject(entity.getBody(), UserInfo.class);
        if (!StringUtils.isEmpty(userInfo.getErrcode())) {
            throw new RuntimeException(userInfo.getErrmsg());
        }
        userMap.put(authCode, userInfo);
        return userInfo;
    }

    @Override
    public String getMessageByReqMsg(String reqMsg) {
        BaseMessage baseMessage = JaxpUtil.fromXML(reqMsg, BaseMessage.class);
        switch (baseMessage.getMsgType()) {
            case WeChatConstant.RESP_MESSAGE_TYPE_TEXT:
                TextMessage textMessage = getTextMessageBD(reqMsg);
                return JaxpUtil.toXML(textMessage);
            default:
                TextMessage textMessageDef = generateTextMessage(baseMessage.getFromUserName(), baseMessage.getFromUserName(), "不支持的消息类型：" + baseMessage.getMsgType());
                return JaxpUtil.toXML(textMessageDef);
        }
    }

    @Override
    public TextMessage getTextMessageBD(String reqMsg) {
        TextMessage reqMessage = JaxpUtil.fromXML(reqMsg, TextMessage.class);
        String content = "百度接口正在测试：" + reqMessage.getContent();
        TextMessage textMessage = generateTextMessage(reqMessage.getFromUserName(), reqMessage.getToUserName(), content);
        return textMessage;
    }
}
